package com.tonghu.bluetoothregistration;

import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Environment;
import android.os.IBinder;
import android.support.v7.app.ActionBarActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toast;

import com.tonghu.bluetoothregistration.service.BluetoothLeService;
import com.tonghu.bluetoothregistration.utils.OU;
import com.tonghu.bluetoothregistration.view.CameraPreview;

import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.Extra;
import org.androidannotations.annotations.ViewById;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * Created by tonghu on 6/7/15.
 */
@EActivity(R.layout.activity_take_picture)
public class TakePictureActivity extends ActionBarActivity{
    public static final String EXTRA_MAC = "extra_mac";
    private static final String TAG = "tonghu";
    private BluetoothLeService mBluetoothLeService;
    private Camera mCamera;
    private CameraPreview mPreview;
    @ViewById
    FrameLayout contentView;

    @ViewById
    ImageView imageView;

    @Extra(EXTRA_MAC)
    String mac;

    @AfterViews
    void afterViews() {

        if (TextUtils.isEmpty(mac)) {
            Toast.makeText(this, "没有获取到mac地址", Toast.LENGTH_LONG).show();
            finish();
            return;
        }

        mCamera = getCameraInstance();
        mPreview = new CameraPreview(this, mCamera);
        contentView.addView(mPreview);

        Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
        bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
    }

    @Click
    void imageView(View view) {
        Log.i("tonghu", "TakePictureActivity, imageView(L82): ");
        if (view.getTag() != null) {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType((Uri) view.getTag(), "image/*");
            startActivity(intent);
        }
    }

    private Camera.PictureCallback mPicture = new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            //将得到的照片进行270°旋转，使其竖直
            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
            Matrix matrix = new Matrix();
            matrix.preRotate(270);
            bitmap = Bitmap.createBitmap(bitmap ,0,0, bitmap .getWidth(), bitmap
                    .getHeight(),matrix,true);

            File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
            if (pictureFile == null){
                Log.d(TAG, "Error creating media file, check storage permissions: "
//                                +
                        /*e.getMessage()*/);
                return;
            }

            try {
                FileOutputStream fos = new FileOutputStream(pictureFile);
//                fos.write(data);
//                fos.close();
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
                Toast.makeText(TakePictureActivity.this, "拍照成功!", Toast.LENGTH_LONG).show();
                imageView.setImageURI(Uri.fromFile(pictureFile));
                imageView.setTag(Uri.fromFile(pictureFile));
            } catch (FileNotFoundException e) {
                Log.d(TAG, "File not found: " + e.getMessage());
            } catch (IOException e) {
                Log.d(TAG, "Error accessing file: " + e.getMessage());
            }
        }
    };

    public static final int MEDIA_TYPE_IMAGE = 1;
    public static final int MEDIA_TYPE_VIDEO = 2;

    /** Create a File for saving an image or video */
    private static File getOutputMediaFile(int type){
        // To be safe, you should check that the SDCard is mounted
        // using Environment.getExternalStorageState() before doing this.

        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES), "MyCameraApp");
        // This location works best if you want the created images to be shared
        // between applications and persist after your app has been uninstalled.

        // Create the storage directory if it does not exist
        if (! mediaStorageDir.exists()){
            if (! mediaStorageDir.mkdirs()){
                Log.d("MyCameraApp", "failed to create directory");
                return null;
            }
        }

        // Create a media file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File mediaFile;
        if (type == MEDIA_TYPE_IMAGE){
            mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                    "IMG_"+ timeStamp + ".jpg");
        } else if(type == MEDIA_TYPE_VIDEO) {
            mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                    "VID_"+ timeStamp + ".mp4");
        } else {
            return null;
        }
        Log.i("tonghu", "picturefile: " + mediaFile.getAbsolutePath().toString());

        return mediaFile;
    }

    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
        if (mBluetoothLeService != null) {
            final boolean result = mBluetoothLeService.connect(mac);
            Log.d(TAG, "Connect request result=" + result);
        }
    }

    private static IntentFilter makeGattUpdateIntentFilter() {
        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
        intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
        return intentFilter;
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(mGattUpdateReceiver);
    }

    // Code to manage Service lifecycle.
    private final ServiceConnection mServiceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder service) {
            Log.i("tonghu","TakePictureActivity, onServiceConnected(L82): ");
            mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
            if (!mBluetoothLeService.initialize()) {
                Log.e(TAG, "Unable to initialize Bluetooth");
                finish();
            }
            // Automatically connects to the device upon successful start-up initialization.
            mBluetoothLeService.connect(mac);
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mBluetoothLeService = null;
        }
    };

    private boolean mConnected = false;


    private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
                mConnected = true;
//                updateConnectionState(R.string.connected);
                invalidateOptionsMenu();
            } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
                mConnected = false;
//                updateConnectionState(R.string.disconnected);
                invalidateOptionsMenu();
//                clearUI();
            } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
                // Show all the supported services and characteristics on the user interface.
//                displayGattServices(mBluetoothLeService.getSupportedGattServices());
                Toast.makeText(TakePictureActivity.this, "连接成功", Toast.LENGTH_LONG).show();
                List<BluetoothGattService> supportedGattServices = mBluetoothLeService.getSupportedGattServices();
                boolean shouldBreak = false;
                for (BluetoothGattService bluetoothLeService: supportedGattServices) {
                    List<BluetoothGattCharacteristic> characteristics = bluetoothLeService.getCharacteristics();
                    for (BluetoothGattCharacteristic characteristic : characteristics) {
//                        Log.i("tonghu","TakePictureActivity, onReceive(L121): " + characteristic.getUuid().toString());
                        if (characteristic.getUuid().toString().equals("0000ffe1-0000-1000-8000-00805f9b34fb")) {
                            Log.i("tonghu","TakePictureActivity, onReceive(L124): set notifycation");
                            mBluetoothLeService.setCharacteristicNotification(characteristic, true);
                            shouldBreak = true;
                            break;
                        }
                    }
                    if (shouldBreak) {
                        break;
                    }
                }
            } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
//                displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
                byte[] data = intent.getByteArrayExtra(BluetoothLeService.EXTRA_DATA);
                Log.i("tonghu","TakePictureActivity, onReceive(L130): " + OU.bytesToHex(data));
                if (OU.byteArrayEquals(new byte[]{0x01}, intent.getByteArrayExtra(BluetoothLeService.EXTRA_DATA))) {
                    Log.i("tonghu", "TakePictureActivity, onReceive(L140): the same");
                    if (mCamera != null) {
                        try {
                            mCamera.takePicture(null, null, mPicture);
                        } catch (Exception e) {
                            e.printStackTrace();
                            Toast.makeText(TakePictureActivity.this, "拍照失败，请重试", Toast.LENGTH_LONG).show();
                        }
                    }
                }
            }
        }
    };

    /** Check if this device has a camera */
    private boolean checkCameraHardware(Context context) {
        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
            // this device has a camera
            return true;
        } else {
            // no camera on this device
            return false;
        }
    }

    /** A safe way to get an instance of the Camera object. */
    public static Camera getCameraInstance(){
        Camera c = null;
        try {
            c = Camera.open(1); // attempt to get a Camera instance
            if (c != null) {
                c.setDisplayOrientation(90);
            }
        }
        catch (Exception e){
            // Camera is not available (in use or does not exist)
        }
        return c; // returns null if camera is unavailable
    }

}
